<?php


namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Video;
use App\Models\VoteLog;
use App\Models\ExcelUser;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use GuzzleHttp\Exception\GuzzleException;

class UserController extends Controller
{
//    const APP_ID       = 'dingsq2xel5jq13qh6q3';
//    const APP_SECRET   = 'axciNAmZytl4xjuUXfZ7EFz2PBL7gyyfT1yDT3N9cQ5cpfHXs_rhpZv3Y1cOeDz5';
    const MAX_VOTE_NUM = 3;
    const APP_ID       = 'ding4jqqsda3uvynmofb';
    const APP_SECRET   = 'OxtN43Ci-Xy_MZhlFao-mWK_Gitbf2dmpcXTabYbu8sxLv-bYVphW9IqO_m3Gq9L';

    private $code;

    public function vote(Request $request)
    {
        $videoID = $request->post('videoID');
        $userID  = $request->cookie('login-token');
        $userIDPost = $request->post('loginToken');

        if (empty($userID) && (empty($userIDPost) || $userIDPost == 'undefined' || $userIDPost == 'null')) {
            Log::info(sprintf('no user id'));
            return $this->responseJson(403, '请登录吧');
        }

        $userID = $userID ?: $userIDPost;

        if (empty($videoID)) {
            return $this->responseJson(204, 'require post param videoID');
        }

        $userInfo = User::query()->find($userID);

        if (empty($userInfo)) {
            Log::info(sprintf('no user info %s' ,$userID));
            return $this->responseJson(403, '请登录');
        }

        $video = Video::query()->find($videoID);

        if (empty($video)) {
            return $this->responseJson(201, '不存在的视频');
        }

        $logs = VoteLog::query()->where('userID', $userID)->get();

        if (count($logs) >= 1) {
            return $this->responseJson(202, '投票次数超过上限');
        }

        foreach ($logs as $log) {
            if ($log->videoID == $videoID) {
                return $this->responseJson(203, '已经给该视频投过票了');
            }
        }

        DB::transaction(function () use ($video, $userID) {
            $video->increment('votes');

            $model          = new VoteLog();
            $model->videoID = $video->id;
            $model->userID  = $userID;
            $model->save();

        }, 5);

        return $this->responseJson(200);
    }

    public function login(Request $request)
    {
        $this->code = $request->post('code');

        if (empty($this->code)) {
            return $this->responseJson(100, 'require post param code');
        }

        $token = $this->getAccessToken();

        if (empty($token)) {
            return $this->responseJson(101, 'get AccessToken error');
        }

        $userID = $this->getUserID($token);

        if (empty($userID)) {
            return $this->responseJson(102, 'code 已失效');
        }

        $userInfo = $this->getUserInfo($token, $userID);

        $dbUserInfo = User::query()->where('ddUserID', $userID)->first();

        if (empty($dbUserInfo)) {
            $dbUserInfo = new User();
        }

        $dbUserInfo->updateAt = date('Y-m-d H:i:s');
        $dbUserInfo->avatar   = $userInfo['avatar'] ?? '';
        $dbUserInfo->userName = $userInfo['name'] ?? '';
        $dbUserInfo->createAt = date('Y-m-d H:i:s');
        $dbUserInfo->ddUserID = $userID;

        $res = $dbUserInfo->save();

        if (empty($res)) {
            return $this->responseJson(104, 'login error');
        }

        return $this->responseJson(200 ,'success',['loginToken' => $dbUserInfo->id])->cookie("login-token", $dbUserInfo->id, 3600 * 6);
    }


    public function bind(Request $request)
    {
        $userName   = $request->post('userName');
        $passwd     = $request->post('passwd');
        $this->code = $request->post('code');

        if (mb_strlen($userName) < 6) {
            return $this->responseJson(303, '用户名需要大于6位');
        }

        if (mb_strlen($userName) > 20) {
            return $this->responseJson(305, '用户名需要小于20位');
        }

        if (mb_strlen($passwd) < 6) {
            return $this->responseJson(304, '密码需要大于6位');
        }

        if (mb_strlen($passwd) > 20) {
            return $this->responseJson(307, '密码需要小于20位');
        }

        $token = $this->getAccessToken();

        if (empty($token)) {
            return $this->responseJson(101, 'get AccessToken error');
        }

        $userID = $this->getUserID($token);

        if (empty($userID)) {
            return $this->responseJson(102, 'code 失效');
        }

        $dbUserInfo = User::query()->where('ddUserID', $userID)->first();

        if (!empty($dbUserInfo)) {
            return $this->responseJson(200)->cookie("login-token", $dbUserInfo->id, 3600 * 6);
        }

        $userInfo = $this->getUserInfo($token, $userID);

        $dbUserInfo           = new User();
        $dbUserInfo->updateAt = date('Y-m-d H:i:s');
        $dbUserInfo->avatar   = $userInfo['avatar'] ?? '';
        $dbUserInfo->userName = $userInfo['name'] ?? '';
        $dbUserInfo->createAt = date('Y-m-d H:i:s');
        $dbUserInfo->ddUserID = $userID;
        $dbUserInfo->passwd   = md5($passwd);
        $dbUserInfo->account  = $userName;
        $res                  = $dbUserInfo->save();

        if (empty($res)) {
            return $this->responseJson(302, '绑定账户失败 联系管理员处理');
        }

        return $this->responseJson(200)->cookie("login-token", $dbUserInfo->id, 3600 * 6);
    }

    private function getAccessToken()
    {
        $client = new \GuzzleHttp\Client();
        try {
            $res = $client->request('GET',
                sprintf(
                    "https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s",
                    self::APP_ID,
                    self::APP_SECRET
                ));

            /*
             * {
                    "errcode": 0,
                    "errmsg": "ok",
                    "access_token": "fw8ef8we8f76e6f7s8df8s"
                }
             * */
            $body = $res->getBody();

            if (empty($body)) {
                Log::error(sprintf('getAccessToken error msg:%s', 'request success but no res'));
                return false;
            }

            $json = json_decode($body, true);

            return $json['access_token'] ?? false;
        } catch (GuzzleException $e) {
            Log::error(sprintf('getAccessToken error msg:%s', $e->getMessage()));
            return false;
        }
    }

    private function getUserID($token)
    {
        $client = new \GuzzleHttp\Client();
        try {
            $res = $client->request('GET',
                sprintf(
                    "https://oapi.dingtalk.com/user/getuserinfo?access_token=%s&code=%s",
                    $token,
                    $this->code
                ));

            /*
             * {
                "userid": "****",
                "sys_level": 1,
                "errmsg": "ok",
                "is_sys": true,
                "errcode": 0
             * */
            $body = $res->getBody();

            if (empty($body)) {
                Log::error(sprintf('getUserIDn error msg:%s', 'request success but no res'));
                return false;
            }

            $json = json_decode($body, true);

            if (empty($json['userid'])) {
                Log::error(sprintf('getUserIDn error msg:%s', $json['errmsg'] ?? ''));
            }

            return $json['userid'] ?? false;
        } catch (GuzzleException $e) {
            Log::error(sprintf('getUserID error msg:%s', $e->getMessage()));
            return false;
        }
    }

    private function getUserInfo($token, $userID)
    {

        $client = new \GuzzleHttp\Client();
        try {
            $res = $client->request('GET',
                sprintf(
                    "https://oapi.dingtalk.com/user/get?access_token=%s&userid=%s",
                    $token,
                    $userID
                ));

//            $res = $client->post('https://oapi.dingtalk.com/topapi/edu/user/get?access_token=' . $token , ['body' => json_encode(['language'=>'zh_CN' ,'userid' => $userID])]);

            /*
             * {
                    "errcode": 0,
                    "unionid": "PiiiPyQqBNBii0HnCJ3zljcxxxxxx",
                    "remark": "remark",
                    "userid": "zhangsan",
                    "isLeaderInDepts": "{1:false}",
                    "isBoss": false,
                    "hiredDate": 1520265600000,
                    "isSenior": false,
                    "tel": "xxx-xxxxxxxx",
                    "department": [1,2],
                    "workPlace": "place",
                    "email": "test@xxx.com",
                    "orderInDepts": "{1:71738366882504}",
                    "mobile": "1xxxxxxxxxx",
                    "errmsg": "ok",
                    "active": false,
                    "avatar": "xxx",
                    "isAdmin": false,
                    "isHide": false,
                    "jobnumber": "001",
                    "name": "张三",
                    "extattr": {},
                    "stateCode": "86",
                    "position": "manager",
                    "roles": [
                        {
                            "id": 149507744,
                            "name": "总监",
                            "groupName": "职务"
                        }
                    ]
                    }
             * */
            $body = $res->getBody();

            if (empty($body)) {
                Log::error(sprintf('getUserInfo error msg:%s', 'request success but no res'));
                return false;
            }

            $json = json_decode($body, true);

            if (isset($json['errcode']) && !empty($json['errcode'])) {
                return false;
            }

            return $json;
        } catch (GuzzleException $e) {
            Log::error(sprintf('getUserInfo error msg:%s', $e->getMessage()));
            return false;
        }
    }
}
